package com.action.service.component;

import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;

import com.action.entity.Mp3Info;
import com.action.entity.event.MineSwitchEvent;
import com.hwangjr.rxbus.RxBus;
import com.hwangjr.rxbus.annotation.Subscribe;
import com.hwangjr.rxbus.thread.EventThread;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PlayService extends Service implements MediaPlayer.OnCompletionListener,MediaPlayer.OnErrorListener {
    private MediaPlayer mPlayer;
    private int currentPosition;//当前正在播放的歌曲的位置
    ArrayList<Mp3Info> mp3Infos;

    private MusicUpdatrListener musicUpdatrListener;

    //创建一个单实力的线程,用于更新音乐信息
    private ExecutorService es = Executors.newSingleThreadExecutor();

    //播放模式
    public static final int ORDER_PLAY = 1;//顺序播放
    public static final int RANDOM_PLAY = 2;//随机播放
    public static final int SINGLE_PLAY = 3;//单曲循环
    private int play_mode = ORDER_PLAY;//播放模式,默认为顺序播放

    /**
     * @param play_mode
     * ORDER_PLAY = 1;//顺序播放
     * RANDOM_PLAY = 2;//随机播放
     * SINGLE_PLAY = 3;//单曲循环
     */
    //set方法
    public void setPlay_mode(int play_mode) {
        this.play_mode = play_mode;
    }

    //get方法
    public int getPlay_mode() {
        return play_mode;
    }

    private boolean isPause = false;//歌曲播放中的暂停状态

    public boolean isPause(){
        return isPause;
    }

    public PlayService() {
    }

    public int getCurrentPosition(){
        return currentPosition;
    }

    private Random random = new Random();//创建随机对象
    //MediaPlayer.Completion 播放完成 实现播放下一首功能
    //播放完成以后,判断播放模式(曲目循环方式)
    //为了实现循环后,可以显示音乐信息,需要在PlayAcivity的change里添加对应代码
    @Override
    public void onCompletion(MediaPlayer mp) {
        switch (play_mode){
            case ORDER_PLAY://顺序播放
                next();//下一首
                break;
            case RANDOM_PLAY://随机播放
                //currentPosition = random.nextInt(mp3Infos.size());//随机下标为mp3Infos.size()
                //play(currentPosition);
                play(random.nextInt(mp3Infos.size()));
                break;
            case SINGLE_PLAY://单曲循环
                play(currentPosition);
                break;
            default:
                break;
        }
    }
    //MediaPlayer.Error 播放错误 处理实现播放下一首功能出现的错误
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mp.reset();//重启
        return false;
    }

    //内部类PlayBinder实现Binder,得到当前PlayService对象
    class PlayBinder extends Binder {
        public PlayService getPlayService(){
            System.out.println("PlayService #1 " + PlayService.this);
            return PlayService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new PlayBinder();//通过PlayBinder拿到PlayService,给Activity调用
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mPlayer = new MediaPlayer();
        mPlayer.setOnCompletionListener(this);//注册播放完成事件
        mPlayer.setOnErrorListener(this);//注册播放错误事件
        mp3Infos = getMp3Infos();//获取Mp3列表
        es.execute(updateSteatusRunnable);//更新进度值
        start();
        RxBus.get().register(this);
    }
    @Subscribe(thread = EventThread.MAIN_THREAD)
    public void consumeMineSwitchEvent(MineSwitchEvent mineSwitchEvent){
        if(mineSwitchEvent.getType()==0){
            start();
        }else{
            pause();
        }
    }
    private ArrayList<Mp3Info> getMp3Infos() {
        ArrayList<Mp3Info> mp3Infos=new ArrayList<>();
        Mp3Info mp3Info=new Mp3Info();
        mp3Info.setFilePath("wakuang_ing.mp3");
        mp3Infos.add(mp3Info);
        return mp3Infos;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //回收线程
        if (es!=null && !es.isShutdown()){//当进度值等于空,并且,进度值没有关闭
            es.shutdown();
            es = null;
        }
    }

    //利用Runnable来实现多线程
    /**
     * Runnable
     * Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口.
     * Runnable接口非常简单,就定义了一个方法run(),继承Runnable并实现这个
     * 方法就可以实现多线程了,但是这个run()方法不能自己调用,必须由系统来调用,否则就和别的方法没有什么区别了.
     * 好处:数据共享
     */
    Runnable updateSteatusRunnable = new Runnable() {//更新状态
        @Override
        public void run() {
            //不断更新进度值
            while (true){
                //音乐更新监听不为空,并且,媒体播放不为空,并且媒体播放为播放状态
                if(musicUpdatrListener!=null && mPlayer!=null && mPlayer.isPlaying()){
                    musicUpdatrListener.onPublish(getCurrentProgress());//获取当前的进度值
                }
                try {
                    Thread.sleep(500);//500毫秒更新一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    //播放
    public void play(int position){
        AssetManager am = getAssets();

        if (position>=0 && position<mp3Infos.size()){
            Mp3Info mp3Info = mp3Infos.get(position);//获取mp3Info对象
            //进行播放,播放前判断
            try {
                mPlayer.reset();//重启
                AssetFileDescriptor afd = am.openFd(mp3Info.getFilePath());
                mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getStartOffset());//资源解析,Mp3地址
                mPlayer.prepare();//准备
                mPlayer.start();//开始(播放)
                currentPosition = position;//保存当前位置到currentPosition,比如第一首,currentPosition = 1
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(musicUpdatrListener!=null){
                musicUpdatrListener.onChange(currentPosition);//更新当前位置
            }
        }
    }

    //暂停
    public void pause(){
        if (mPlayer.isPlaying()){
            mPlayer.pause();
            isPause = true;
        }
    }

    //下一首
    public void next(){
        if (currentPosition>=mp3Infos.size()-1){//如果超出最大值,(因为第一首是0),说明已经是最后一首
            currentPosition = 0;//回到第一首
        }else {
            currentPosition++;//下一首
        }
        play(currentPosition);
    }

    //上一首 previous
    public void prev(){
        if (currentPosition-1<0){//如果上一首小于0,说明已经是第一首
            currentPosition = mp3Infos.size()-1;//回到最后一首
        }else {
            currentPosition--;//上一首
        }
        play(currentPosition);
    }

    //默认开始播放的方法
    public void start(){
        if (mPlayer!=null && !mPlayer.isPlaying()){//判断当前歌曲不等于空,并且没有在播放的状态
            mPlayer.start();

        }
    }

    //获取当前是否为播放状态,提供给MyMusicListFragment的播放暂停按钮点击事件判断状态时调用
    public boolean isPlaying(){
        if (mPlayer!=null){
            return mPlayer.isPlaying();
        }
        return false;
    }

    //获取当前的进度值
    public int getCurrentProgress(){
        if(mPlayer!=null && mPlayer.isPlaying()){//mPlayer不为空,并且,为播放状态
            return mPlayer.getCurrentPosition();
        }
        return 0;
    }
    //getDuration 获取文件的持续时间
    public int getDuration(){
        return mPlayer.getDuration();
    }
    //seekTo 寻找指定的时间位置
    public void seekTo(int msec){
        mPlayer.seekTo(msec);
    }

    //更新状态的接口(PlayService的内部接口),并在BaseActivity中实现
    public interface MusicUpdatrListener{//音乐更新监听器
        public void onPublish(int progress);//发表进度事件(更新进度条)
        public void onChange(int position); //更新歌曲位置.按钮的状态等信息
        //声明MusicUpdatrListener后,添加set方法
    }

    //set方法
    public void setMusicUpdatrListener(MusicUpdatrListener musicUpdatrListener) {
        this.musicUpdatrListener = musicUpdatrListener;
    }

}
